/**
 * @asignatura: Procesadores de Lenguajes.
 * @autor:      Anthony Vittorio Russo Cabrera
 * @curso:      2012/2013
 * @práctica:   02 - Pseudo-Analizador Léxico
 * @descripción:
 * Práctica 2: Comenzando con Analizador Léxico
 * En la práctica de esta semana vamos a plantear el acercamiento a un 
 * analizador léxico. Objetivo: Construir un pseudo-analizador léxico que cumpla
 * con las siguientes tareas:
 *  1.- Detectar que un código JAVA se encuentran dentro del conjunto de 
 *  caracteres especificado en un fichero, este puede venir dado por un fichero
 *  de texto o por un XML.
 *  2.- Detectar que este código JAVA, las palabras reservadas que 
 *  especificaremos en un fichero, este puede venir dado por un fichero de texto
 *  o por un XML.
 *  3.- Detectar el conjunto de bloques y especificarlos en la salida de la
 *  práctica.
 *  4.- La práctica debe contener un test unitario para cada uno de las tareas
 *  mencionadas. Y debe ser compilada y ejecutada a través de un fichero ANT.
 *  5.- La práctica debe tener sus propios test de comprobación
 */
package pl.p02;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import nu.xom.Builder;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;
import nu.xom.ValidityException;

public class Keywords {

  private FileReader               file     = null;
  private HashMap<String, Integer> keywords = null; // keywords -> occurrence

  public Keywords(String pathFile) {
    keywords = new HashMap<String, Integer>();
    try {
      file = new FileReader(pathFile);
      if (pathFile.matches(".*xml$")) {
        xmlReader();
      } else {
        txtReader();
      }// ifelse
      file.close();

    } catch (FileNotFoundException e) {
      System.err.println("ERROR->Keyword.Constructor.FileNotFoundException:");
      System.err.println("No se encuentra el fichero '" + pathFile + "'");
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println("ERROR->Keyword.Constructor.IOException:");
      System.err.println("file.close()");
      e.printStackTrace();
    }// try-catch
  }// Constructor

  private void xmlReader() {
    try {
      // Construir el árbol DOM a partir del fichero xml
      Document doc = new Builder().build(file);
      // Obtener el elemento raíz del árbol
      Element root = doc.getRootElement();
      Elements children = root.getChildElements();
      for (int i = 0; i < children.size(); i++) {
        Element child = children.get(i);
        keywords.put(child.getValue(), new Integer(0));
      }// for

    } catch (ValidityException e) {
      System.err.println("Keyword.xmlReader.ValidityException->ERROR");
      e.printStackTrace();
    } catch (ParsingException e) {
      System.err.println("Keyword.xmlReader.ParsingException->ERROR");
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println("Keyword.xmlReader.IOException->ERROR");
      e.printStackTrace();
    } // try-catch
  }// xmlReader

  private void txtReader() {
    try {
      BufferedReader wordOneByLine = new BufferedReader(file);
      String keyword = null;
      while ((keyword = wordOneByLine.readLine()) != null) {
        keywords.put(keyword, new Integer(0));
      }// while
    } catch (IOException e) {
      System.err.println("Keyword.txtReader.IOException->ERROR");
      System.err.println("No se puede leer el fichero");
      e.printStackTrace();
    }
  }// txtReader

  public void parse(String line) {
    String[] words = line.split("[\\s\\p{Punct}]+");
    for (String word : words) {
      if (keywords.containsKey(word)) {
        keywords.put(word, keywords.get(word) + 1);
      }// if
    }// for
  }// parse

  public String report() {
    String result = "Palabras reservadas encontradas:\n"
        + "<keyword> -> 'x' times\n"
        + "--------------------------------------------\n";
    Integer ocurrences = 0;
    for (String keyword : keywords.keySet()) {
      if ((ocurrences = keywords.get(keyword)) != 0) {
        result += "<" + keyword + "> -> '" + ocurrences.toString()
            + "' times\n";
      }// if
    }// for
    result += "--------------------------------------------\n";
    return result;
  }// report

}// Keywords
